package net.zoneland.knowledge.controller;

import com.google.common.base.Preconditions;
import net.zoneland.knowledge.enums.SecretaryProjectFormExcelEnum;
import net.zoneland.knowledge.model.*;
import net.zoneland.knowledge.service.SecretaryProjectService;
import net.zoneland.knowledge.service.bean.ResultInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

/**
 * 书记项目处理控制器.
 *
 * @author shengh
 */
@RestController
@RequestMapping("/api/secretary")
public class SecretaryProjectController extends AbstractBaseApplyInfoController {
    /**
     * 日志.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(SecretaryProjectController.class);

    /**
     * 保存工单信息异常提示语.
     */
    private static final String SAVE_APPLY_INFO_EXCEPTION = "保存工单信息异常";

    /**
     * 提交草稿工单信息异常提示语.
     */
    private static final String SUBMIT_DRAFT_EXCEPTION = "提交草稿工单信息异常";

    /**
     * 获取决策信息异常提示语.
     */
    private static final String DECISION_INFO_EXCEPTION = "获取决策信息异常";

    /**
     * 获取下一节点信息异常提示语.
     */
    private static final String NEXT_NODE_INFO_EXCEPTION = "获取下一节点信息异常";

    /**
     * 下载书记项目的名称(“领题破题 合力攻坚”项目立项审批书.xlsx).
     * {@code URLEncoder.encode("“领题破题 合力攻坚”项目立项审批书.xlsx", "UTF-8")}后的值
     *
     */
    private static final String DOWNLOAD_SECRETARY_PROJECT_APPROVAL_LETTER =
        "%E2%80%9C%E9%A2%86%E9%A2%98%E7%A0%B4%E9%A2%98%20%E5%90%88%E5%8A%9B%E6%94%BB%E5%9D%9A%E2%80%9D%E9%A1%B9%E7%9B%AE%E7%AB%8B%E9%A1%B9%E5%AE%A1%E6%89%B9%E4%B9%A6.xlsx";

    /**
     * 工单信息id不能为空提示语.
     */
    private static final String WORK_APPLY_ID_CAN_NOT_EMPTY = "工单信息id不能为空！";

    /**
     * 工单处理业务接口.
     */
    @Resource
    private SecretaryProjectService secretaryProjectService;

    /**
     * 保存草稿.
     * @param request 请求
     * @return 响应
     */
    @PostMapping("/saveDraft")
    public ResponseResult<Object> saveDraft(final HttpServletRequest request) {

        final ResponseResult<Object> res = new ResponseResult<>();

        try {
            final LoginUserPojo user = getAndCheckCurrentUser(request);
            final WorkApplyInfo info = secretaryProjectService.initSecretaryProject(request, user);
            secretaryProjectService.saveDraft(info, user);
            res.setData(info.getId());
        } catch (final Exception e) {
            LOGGER.error(SAVE_APPLY_INFO_EXCEPTION, e);
            res.setResult(ResponseResult.FAILED_RESULT);
            res.setMessage(SAVE_APPLY_INFO_EXCEPTION + e.getMessage());
        }

        return res;
    }

    /**
     * 提交草稿工单信息.
     * @param request http请求
     * @return 处理结果
     */
    @PostMapping("/submitDraft")
    public ResponseResult<Object> submitDraft(final HttpServletRequest request) {

        final ResponseResult<Object> res = new ResponseResult<>();
        try {
            final LoginUserPojo user = getAndCheckCurrentUser(request);

            // 初始化工单信息
            final WorkApplyInfo info = secretaryProjectService.initSecretaryProject(request, user);

            // 初始化流程处理信息
            final ProcessProcessing processProcessing = secretaryProjectService.initProcessProcessing(request, user);

            // 提交草稿工单
            secretaryProjectService.submitDraft(info, processProcessing, user);
        } catch (final Exception e) {
            LOGGER.error(SUBMIT_DRAFT_EXCEPTION, e);
            res.setResult(ResponseResult.FAILED_RESULT);
            res.setMessage(SUBMIT_DRAFT_EXCEPTION + e.getMessage());
        }
        return res;
    }

    /**
     * 提交工单信息.
     * @param request http请求
     * @return 处理结果
     */
    @PostMapping("/submitSecretaryTask")
    public ResponseResult<Object> submitSecretaryTask(final HttpServletRequest request) {

        final ResponseResult<Object> res = new ResponseResult<>();
        try {
            final LoginUserPojo user = getAndCheckCurrentUser(request);

            // 获取工单信息
            final WorkApplyInfo info = secretaryProjectService.getSecretaryProjectInfo(request, user);

            // 初始化流程处理信息
            final ProcessProcessing processProcessing = secretaryProjectService.initProcessProcessing(request, user);

            secretaryProjectService.submit(info, processProcessing, user);
        } catch (final Exception e) {
            LOGGER.error("提交工单信息异常", e);
            res.setResult(ResponseResult.FAILED_RESULT);
            res.setMessage("提交工单信息异常：" + e.getMessage());
        }
        return res;
    }

    /**
     * 获取决策信息.
     * @param request 请求
     * @return ResponseResult<Object> 决策信息
     */
    @PostMapping("/queryTaskDecisions")
    public ResponseResult<Object> queryTaskDecisions(final HttpServletRequest request) {

        final ResponseResult<Object> res = new ResponseResult<>();

        try{
            final ResultInfo resultInfo = secretaryProjectService.queryTaskDecisions(request);
            res.setData(resultInfo.getData());
        } catch (final Exception e) {
            LOGGER.error(DECISION_INFO_EXCEPTION, e);
            res.setResult(ResponseResult.FAILED_RESULT);
            res.setMessage(DECISION_INFO_EXCEPTION + e.getMessage());
        }

        return res;
    }

    /**
     * 查询业务流程信息.
     * @param request 请求
     * @return ResultInfo 业务流程信息
     */
    @PostMapping("/queryBusinessProcess")
    public ResponseResult<Object> queryBusinessProcess(final HttpServletRequest request) {
        final ResponseResult<Object> res = new ResponseResult<>();

        try {
            final ResultInfo resultInfo = secretaryProjectService.queryBusinessProcess(request);
            res.setData(resultInfo.getData());
        } catch (final Exception e) {
            LOGGER.error("查询业务流程异常", e);
            res.setResult(ResponseResult.FAILED_RESULT);
            res.setMessage("查询业务流程异常" + e.getMessage());
        }
        return res;
    }

    /**
     * 检查获取处理人.
     * @param orgUserSelectItems 选人框信息
     * @return 解析后的人员数据
     */
    @PostMapping("/checkAndGetNextHandler")
    public ResponseResult<List<PartyUserVo>> checkAndGetNextHandler(@RequestBody List<PartyOrgUserSelectItem> orgUserSelectItems) {
        final ResponseResult<List<PartyUserVo>> res = new ResponseResult<>();
        final List<PartyUserVo> users = secretaryProjectService.getResolveNextHandler(orgUserSelectItems);
        final String checkInfo = secretaryProjectService.checkNextHandler(users);
        if (StringUtils.isEmpty(checkInfo)) {
            res.setData(users);
        } else {
            res.setMessage(checkInfo);
            res.setResult(ResponseResult.FAILED_RESULT);
        }
        return res;
    }

    /**
     * 获取下一节点信息.
     * @param request 请求
     * @return 下一节点信息
     */
    @PostMapping("/queryNextNodeInfo")
    public ResponseResult<Object> queryNextNodeInfo(final HttpServletRequest request) {
        final ResponseResult<Object> res = new ResponseResult<>();

        try{
            NextNodeInfo nextNodeInfo = secretaryProjectService.queryNextNodeInfo(request);
            res.setData(nextNodeInfo);
        } catch (final Exception e) {
            LOGGER.error(NEXT_NODE_INFO_EXCEPTION, e);
            res.setResult(ResponseResult.FAILED_RESULT);
            res.setMessage(NEXT_NODE_INFO_EXCEPTION + e.getMessage());
        }

        return res;
    }

    /**
     * 下载书记项目立项书.
     * @param request http请求
     * @param response http响应
     */
    @GetMapping("/downloadSecretaryForm")
    public void downloadSecretaryForm(final HttpServletRequest request, final HttpServletResponse response) {
        // 工单id
        final String workApplyId = request.getParameter(WORK_APPLY_ID_NAME);
        Preconditions.checkArgument(StringUtils.isNotBlank(workApplyId), WORK_APPLY_ID_CAN_NOT_EMPTY);
        final WorkApplyInfo info = workApplyInfoService.findWorkApplyInfoById(workApplyId);

        try (final InputStream classInputStream = ChapterApplyInfoController.class.getResourceAsStream(
            "/excelTemplate/secretaryProjectFormTemplate.xlsx");
             final Workbook workbook = WorkbookFactory.create(classInputStream)) {

            final Sheet sheet = workbook.getSheetAt(0);

            //设置excel的内容
            Arrays.stream(SecretaryProjectFormExcelEnum.values()).forEach(item -> item.setCellValue(sheet, info));

            // 非常重要
            response.reset();
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            response.setContentType("application/x-msdownload");
            response.addHeader("Content-Disposition", "attachment; filename=" + DOWNLOAD_SECRETARY_PROJECT_APPROVAL_LETTER);
            final OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            response.flushBuffer();
        } catch (Exception e) {
            LOGGER.error("下载书记项目立项书出现异常![{}]", e.getMessage());
        }

    }
}
